import subprocess
import numpy as np
from joblib import Parallel, delayed
import os

def run_target_script(solver, req_rate, task_id):
    """
    单个任务：调用外部脚本并实时输出
    
    Args:
        solver (str): 求解器名称
        req_rate (float): 请求速率
        task_id (str): 任务唯一ID (用于区分日志/输出)
    
    Returns:
        str: 任务执行结果（成功/失败信息）
    """
    
    params = [
        f"--id", f"{task_id}",
        f"--req_rate", f"{req_rate:.1f}",  # 保留1位小数，避免浮点数精度问题
        f"--solver", solver,
        "--work_mode", "validate"  # 验证模式（可根据需求改为 train）
    ]
    
    cmd = ["python", "SfcdSagin_main.py"] + params
    print(f"启动仿真: {task_id} | 命令: {' '.join(cmd)}")
    
    try:
        result = subprocess.run(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,  # 合并 stderr 到 stdout，统一捕获
            text=True,
            bufsize=1,
            encoding="utf-8",
            errors="ignore"  # 忽略编码错误，避免中断
        )
        
        # 打印该任务的完整输出（便于调试）
        print(f"\n=== 仿真 {task_id} 输出开始 ===")
        print(result.stdout)
        print(f"=== 仿真 {task_id} 输出结束 ===")
        
        if result.returncode == 0:
            return f"成功: {task_id} | 求解器: {solver} | 速率: {req_rate:.1f}"
        else:
            return f"失败: {task_id} | 求解器: {solver} | 速率: {req_rate:.1f} | 返回码: {result.returncode}"
    
    except Exception as e:
        error_msg = f"异常: {task_id} | 求解器: {solver} | 速率: {req_rate:.1f} | 错误: {str(e)}"
        print(error_msg)
        return error_msg

def main():
    train_solver_params = ["SolverDeployDRLSFCP", "SolverDeployGatDrl", "SolverDeployPPOSFC"]
    heuristic_solver_params = ["SolverDeployLMSFCP"]
    meta_heuristic_solver_params = ["SolverDeploySharedPso"]
    game_theoretic_solver_params = ["SolverDeployPGRA"]
    lyapunov_solver_params = ["SolverDeployTMSM"]
    base_solver_params = ["SolverDeploySharedGreedy", "SolverDeploySharedRandom"]
    
    all_solver_params = list(set(
        lyapunov_solver_params
    ))
    
    req_rate_params = np.arange(2.0, 3.5, 0.5)  # 结果：[0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
    
    tasks = []
    task_count = 0
    for solver in all_solver_params:
        for req_rate in req_rate_params:
            task_count += 1
            task_id = f"{solver}_{req_rate:.1f}"
            tasks.append((solver, req_rate, task_id))
    
    print(f"总任务数: {len(tasks)}")
    print(f"求解器数量: {len(all_solver_params)}")
    print(f"请求速率: {[f'{r:.1f}' for r in req_rate_params]}")
    

    n_jobs = min(os.cpu_count() - 1, 6)
    print(f"\n开始并行执行, 并行进程数: {n_jobs}...")
    
    results = Parallel(
        n_jobs=n_jobs,
        backend="loky",
        verbose=1,
        return_as="list"  # 结果以列表返回
    )(
        delayed(run_target_script)(solver, req_rate, task_id)
        for solver, req_rate, task_id in tasks
    )
    
    # 5. 输出最终执行汇总
    print("\n" + "="*80)
    print("所有任务执行完毕，汇总结果：")
    print("="*80)
    for res in results:
        print(res)
    
    # 统计成功/失败数
    success_count = sum(1 for res in results if res.startswith("成功"))
    fail_count = len(results) - success_count
    print("\n" + "="*80)
    print(f"执行统计: 总任务 {len(tasks)} | 成功 {success_count} | 失败 {fail_count}")
    print("="*80)

if __name__ == "__main__":
    main()
